
/**
 * 界面管理器
 * @class ViewMan
 * @summary 管理游戏中所有的View对象, 单例对象
 * @author IGER
 * @example
let ss = require('ViewMan').share()
ss.translate('LoginView')
 */

class ViewMan {

    static mInstance = null

    static share() 
    {
        this.mInstance || (this.mInstance = new ViewMan())

        return this.mInstance
    }

    constructor() 
    {
        
    }

    init()
    {
        this.mViews         = {}
        this.mNode          = cc.find('Canvas')
        this.mNode.zIndex   = 100
    }

    /**
     * 清除当前所有的界面
     *
     * @param {View} exedView - 需要排除的View对象
     */
    clear(exedView) 
    {
        let v = null

        for (let k in this.mViews) 
        {
            v = this.mViews[k]
            
            if (v && v != exedView && !v.isPersistent) 
            {
                v.close()
                this.mViews[k] = null
            }
        }

        Log.d("view man clear all views..")
    }

    /**
     * 清除当前所有的界面器后跳转到传入的界面
     *
     * @param {String} name - 跳转到的界面名称
     * @param {Object} data - 预传入到跳转界面的逻辑数据，任意类型
     * @param {Function} callback(view) - 跳转完成回调，参数为跳转界面对象
     */
    translate(name, data, callback) 
    {
        this.push(name, data, callback, true) 
    }

    /**
     * 打开界面
     *
     * @param {String} name - 界面名称
     * @param {Object} data - 预传入到界面的逻辑数据，任意类型
     * @param {Function} callback(view) - 跳转完成回调，参数为跳转界面对象
     * @param {Function} callback(view) - 打开完成后,是否清除原来的所有界面
     */
    push(name, data, callback, clearExist, parent) 
    {
        let v = this.viewBy(name)
        if (v)
        {
            return
        }

        let View = require(name)

        v = new View(this, name,
            (view, ok, sysnc) => {

                if (ok)
                {
                    if (clearExist)
                    {
                        this.clear()
                        this.mViews[name] = view
                    }
                    else
                    {
                        if (!this.mViews[name])
                        {
                            if (sysnc)
                            {
                                this.mViews[name] = v
                            }
                            else
                            {
                                return
                            }
                        }
                    }

                    view.open(data)

                    this.notifyViewOpened(view)
                }
                else
                {
                    if (clearExist)
                    {
                        view.close()
                    }
                    else
                    {
                        this.pop(view)
                    }
                    view = null
                }

                if (callback)
                {
                    callback(view)
                }
            }, parent)

        if (!clearExist)
        {
            this.mViews[name] = v
        }
        
        return v
    }

    /**
     * 弹出界面
     *
     * @param {Object} view - 界面名称或者界面对象
     * @return {Boolean}  返回成功或者失败
     */
    pop(view, immediately) 
    {
        let v = typeof(view) == 'string' ? this.mViews[view] : view
        if (!v)
        {
            return false
        }

        this.mViews[v.name()] = null

        if (immediately || !v.requestClose())
        {
            v.close()
        }
        
        return true
    }

    /**
     * 响应消息事件
     *
     * @param {Object} e - 事件对象{ type:Evt.USER_DIRTY, data:user}
     */
    responseEvent(e) 
    {
        let v = null

        for (let k in this.mViews) 
        {
            v = this.mViews[k]

            if (v && v.onEvent) 
            {
                v.onEvent(e)
            }
        }
    }

    notifyViewOpened(view) 
    {
        if (this.mListeners)
        {
            for (let v of this.mListeners) 
            {
                v.notifyViewOpened(view)
            }
        }
    }

    addListener(ls)
    {
        if (this.mListeners)
        {
            if (this.mListeners.indexOf(ls) >= 0)
            {
                return
            }

            this.mListeners.push(ls)
        }
        else
        {
            this.mListeners = [ls]
        }
    }

    removeListener(ls)
    {
        if (this.mListeners)
        {
            let i = this.mListeners.indexOf(ls)
            if (i >= 0)
            {
                this.mListeners.splice(i, 1)
            }
        }
    }

    /**
     * 获取界面管理器根对象
     *
     * @return {cc.Node} 界面管理器根对象
     */
    rootBy() 
    {
        return this.mNode
    }

    /**
     * 根据界面名称，返回界面对象
     *
     * @param {String} name - 界面名称
     * @return {View}
     */
    viewBy(name) 
    {
        return this.mViews[name]
    }
}

export default ViewMan
